package cn.mooncode.basketballManage.service.impl;

import cn.hutool.json.JSONObject;
import cn.mooncode.basketballManage.config.security.JwtTokenUtil;
import cn.mooncode.basketballManage.mapper.RoleMapper;
import cn.mooncode.basketballManage.mapper.UserMapper;
import cn.mooncode.basketballManage.mapper.UserRoleMapper;
import cn.mooncode.basketballManage.pojo.RespBean;
import cn.mooncode.basketballManage.pojo.Role;
import cn.mooncode.basketballManage.pojo.User;
import cn.mooncode.basketballManage.pojo.UserRole;
import cn.mooncode.basketballManage.service.IUserService;
import cn.mooncode.basketballManage.utils.QiniuUploadUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jwz
 * @since 2021-03-28
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Value("${jwt.tokenHead}")
    private String tokenHead;


    /**
     * 登录后返回token
     *
     * @param username
     * @param password
     * @param code
     * @param request
     * @return
     */
    @Override
    public RespBean login(String username, String password, HttpServletRequest request) {
//        登录
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (null == userDetails || !passwordEncoder.matches(password, userDetails.getPassword())) {
            return RespBean.error("用户名或密码不正确！");
        }
        if (!userDetails.isEnabled()) {
            return RespBean.error("账号不可用，请联系管理员！");
        }
//        更新security为当前对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//        生成token
        String token = jwtTokenUtil.generateToken(userDetails);
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return RespBean.success("登录成功", tokenMap);
    }

    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     */
    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectOne(new QueryWrapper<User>().eq("username", username).eq(
                "isenabled", true));
    }

    /**
     * 根据id获取角色
     * @param userid
     * @return
     */
    @Override
    public List<Role> getRoles(Integer userid) {
        return roleMapper.getRoles(userid);
    }

    /**
     * 获取所有用户
     * @param keywords
     * @return
     */
    @Override
    public List<User> getAllUsers(String keywords) {
        return userMapper.getAllUsers(keywords);
    }

    /**
     * 更新用户角色
     * @param id
     * @param rid
     * @return
     */
    @Override
    @Transactional
    public RespBean updateUserRole(Integer id, Integer rid) {
//        清空用户角色表中对应用户所有角色
        userRoleMapper.delete(new QueryWrapper<UserRole>().eq("uid", id));
//        添加新的角色
        Integer result = userRoleMapper.addUserRole(id, rid);
        if (1 == result) {
            return RespBean.success("修改成功！");
        }
        return RespBean.error("修改失败！");
    }

    /**
     * 更新用户密码
     * @param oldPass
     * @param pass
     * @param userId
     * @return
     */
    @Override
    public RespBean updateUserPassword(String oldPass, String pass, Integer userId) {
//        获取要修改密码的用户
        User user = userMapper.selectById(userId);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
//        判断旧密码是否正确
        if (encoder.matches(oldPass, user.getPassword())) {
            user.setPassword(encoder.encode(pass));
            int result = userMapper.updateById(user);
            if (1 == result) {
                return RespBean.success("密码修改成功！");
            }
        }
        return RespBean.error("密码修改失败！");
    }

    /**
     * 删除用户信息
     * @param id
     * @return
     */
    @Override
    @Transactional
    public RespBean deleteUser(Integer id) {
//        首先根据用户id删除用户角色表中对应的用户
        userRoleMapper.delete(new QueryWrapper<UserRole>().eq("uid", id));
//        删除用户
        if (1 == userMapper.deleteById(id)) {
            return RespBean.success("删除成功！");
        }
        return RespBean.error("删除失败！");
    }

    /**
     * 上传头像
     * @param multipartFile
     * @return
     */
    @Override
    public Object avatar(MultipartFile multipartFile) throws IOException {
//        将传入文件转成byte数组
        byte[] imgByte = multipartFile.getBytes();
        String imageUrl = QiniuUploadUtils.upLoadImage(imgByte);
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("avatarUrl", imageUrl);
        return RespBean.success("上传成功！", jsonObject);
    }
}
